﻿namespace QuantBox.XApi
{
    internal static class UfxConvert
    {
        private const sbyte FutureOpen = (sbyte)'1';
        private const sbyte FutureClose = (sbyte)'2';
        private const sbyte FutureCloseToday = (sbyte)'1';

        public static string GetMarketNo(string exchangeId)
        {
            var type = XApiHelper.GetExchangeType(exchangeId);
            switch (type) {
                case ExchangeType.SHFE:
                    return UfxMarketNo.V3;
                case ExchangeType.DCE:
                    return UfxMarketNo.V7;
                case ExchangeType.CZCE:
                    return UfxMarketNo.V4;
                case ExchangeType.CFFEX:
                    return UfxMarketNo.V6;
                case ExchangeType.INE:
                    return UfxMarketNo.V8;
                case ExchangeType.SSE:
                    return UfxMarketNo.V1;
                case ExchangeType.SZSE:
                    return UfxMarketNo.V2;
                default:
                    return string.Empty;
            }
        }

        public static bool IsBond(string exchangeId, string instrumentId)
        {
            var type = XApiHelper.GetExchangeType(exchangeId);
            if (type == ExchangeType.SSE) {
                var flag = instrumentId[0];
                if (flag == '1' || flag == '2') {
                    return true;
                }
                if (flag == '0') {
                    var code = instrumentId.Substring(0, 3);
                    switch (code) {
                        case "009":
                        case "010":
                        case "019":
                        case "020":
                        case "090":
                        case "099":
                            return true;
                    }
                }
            }
            else if (type == ExchangeType.SZSE) {
                var code = instrumentId.Substring(0, 2);
                switch (code) {
                    case "10":
                    case "11":
                    case "12":
                    case "13":
                        return true;
                }
            }
            return false;
        }

        public static string GetEntrustDirection(OrderSide side)
        {
            return side == OrderSide.Buy ? UfxEntrustDirection.V1 : UfxEntrustDirection.V2;
        }

        public static sbyte GetFutureDirection(OpenCloseType openClose)
        {
            return openClose == OpenCloseType.Open ? FutureOpen : FutureClose;
        }

        public static OpenCloseType GetOpenClose(sbyte flag)
        {
            return flag == FutureClose ? OpenCloseType.Close : OpenCloseType.Open;
        }

        public static OpenCloseType GetTradeOpenClose(sbyte flag)
        {
            switch (flag) {
                case (sbyte)'0':
                    return OpenCloseType.Open;
                case (sbyte)'5':
                    return OpenCloseType.CloseToday;
                default:
                    return OpenCloseType.Close; 
            }
        }

        public static OpenCloseType GetOpenClose(string marketNo, sbyte direction, sbyte close)
        {
            if (direction == FutureOpen) {
                return OpenCloseType.Open;
            }

            if (marketNo == UfxMarketNo.V3 && close == FutureCloseToday) {
                return OpenCloseType.CloseToday;
            }
            return OpenCloseType.Close;
        }

        public static sbyte GetUfxPriceType(OrderType type)
        {
            return type == OrderType.Market ? UfxPriceType.V2 : UfxPriceType.V1;
        }
        
        public static OrderStatus GetOrderStatus(sbyte flag)
        {
            switch (flag) {
                case UfxEntrustState.V1:
                    return OrderStatus.NotSent;
                case UfxEntrustState.V2:
                case UfxEntrustState.V3:
                    return OrderStatus.PendingNew;
                case UfxEntrustState.V4:
                case UfxEntrustState.V11:
                    return OrderStatus.New;
                case UfxEntrustState.V5:
                case UfxEntrustState.V12:
                    return OrderStatus.Rejected;
                case UfxEntrustState.V6:
                    return OrderStatus.PartiallyFilled;
                case UfxEntrustState.V7:
                    return OrderStatus.Filled;
                case UfxEntrustState.V8:
                case UfxEntrustState.V9:
                    return OrderStatus.Cancelled;
                case UfxEntrustState.V10:
                case UfxEntrustState.V13:
                case UfxEntrustState.V14:
                case UfxEntrustState.V15:
                case UfxEntrustState.V16:
                case UfxEntrustState.V17:
                case UfxEntrustState.V18:
                    return OrderStatus.PendingCancel;
                default:
                    return OrderStatus.PendingCancel;
            }
        }

        public static OrderSide GetOrderSide(string flag)
        {
            switch (flag) {
                case UfxEntrustDirection.V1:
                case UfxEntrustDirection.V3:
                case UfxEntrustDirection.V10:
                case UfxEntrustDirection.V13:
                case UfxEntrustDirection.V26:
                case UfxEntrustDirection.V36:
                case UfxEntrustDirection.V28:
                    return OrderSide.Buy;
                default:
                    return OrderSide.Sell;
            }
        }

        public static string GetExchange(string marketNo)
        {
            switch (marketNo) {
                case UfxMarketNo.V1:
                    return ExchangeNames.SSE;
                case UfxMarketNo.V2:
                    return ExchangeNames.SZSE;
                case UfxMarketNo.V3:
                    return ExchangeNames.SHFE;
                case UfxMarketNo.V4:
                    return ExchangeNames.CZCE;
                case UfxMarketNo.V6:
                    return ExchangeNames.CFFEX;
                case UfxMarketNo.V7:
                    return ExchangeNames.DCE;
                case UfxMarketNo.V8:
                    return ExchangeNames.INE;
                case UfxMarketNo.V9:
                    return "股转市场";
                case UfxMarketNo.V10:
                    return "港股通(沪)";
                case UfxMarketNo.V11:
                    return "港股通(深)";
                default:
                    return marketNo;
            }
        }

        public static PositionSide GetPositionSide(sbyte side)
        {
            switch (side) {
                case UfxPositionFlag.V1:
                    return PositionSide.Long;
                default:
                    return PositionSide.Short;
            }
        }

        public static OrderType GetOrderType(sbyte type)
        {
            switch (type) {
                case UfxPriceType.V1:
                    return OrderType.Limit;
                default:
                    return OrderType.Market;
            }
        }
    }
}